import os
import shutil
from datetime import datetime
import re
import logging
from logging.handlers import RotatingFileHandler


def setup_logger():
    """配置日志记录器"""
    # 创建logs目录（如果不存在）
    log_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'logs')
    os.makedirs(log_dir, exist_ok=True)

    # 设置日志文件名（带时间戳）
    log_file = os.path.join(
        log_dir,
        f"desktop_organizer_{datetime.now().strftime('%Y%m%d_%H%M%S')}.log"
    )

    # 创建日志记录器
    logger = logging.getLogger('DesktopOrganizer')
    logger.setLevel(logging.INFO)

    # 创建文件处理器（限制每个日志文件10MB，保留5个备份）
    file_handler = RotatingFileHandler(
        log_file,
        maxBytes=10 * 1024 * 1024,
        backupCount=5,
        encoding='utf-8'
    )
    file_handler.setFormatter(logging.Formatter(
        '%(asctime)s - %(levelname)s - %(message)s'
    ))

    # 添加处理器
    logger.addHandler(file_handler)

    # 同时输出到控制台
    console_handler = logging.StreamHandler()
    console_handler.setFormatter(logging.Formatter('%(message)s'))
    logger.addHandler(console_handler)

    return logger


def is_person_name(filename):
    """判断文件名是否是人名"""
    # 中文人名正则（2-4个中文字符）
    chinese_name_pattern = re.compile(r'^[\u4e00-\u9fa5]{2,4}')
    # 英文人名正则（首字母大写的单词）
    english_name_pattern = re.compile(r'^[A-Z][a-z]+')

    # 去除扩展名
    name = os.path.splitext(filename)[0]

    # 检查是否符合中文或英文人名模式
    return bool(chinese_name_pattern.match(name)) or (bool(english_name_pattern.match(name)))


def classify_desktop_files(logger):
    """整理桌面文件的主函数"""
    # 获取桌面路径
    desktop_path = os.path.join(os.path.expanduser('~'), 'Desktop')
    logger.info(f"开始整理桌面文件，桌面路径: {desktop_path}")

    # 获取当前时间
    now = datetime.now()
    time_str = now.strftime("%m%d%H")  # 月日小时 格式，如062411

    # 创建主文件夹
    main_folder = os.path.join(desktop_path, time_str)
    os.makedirs(main_folder, exist_ok=True)
    logger.info(f"创建主文件夹: {time_str}")

    # 文件类型映射
    type_folders = {
        'excel': ['.xlsx', '.xls', '.csv'],
        'word': ['.docx', '.doc'],
        'ppt': ['.pptx', '.ppt'],
        'pdf': ['.pdf'],
        'image': ['.jpg', '.jpeg', '.png', '.gif', '.bmp', '.tiff']
    }

    # 需要处理的扩展名集合（从type_folders中提取）
    target_exts = set()
    for exts in type_folders.values():
        target_exts.update(exts)

    moved_files = 0
    skipped_files = 0

    # 遍历桌面文件
    for filename in os.listdir(desktop_path):
        file_path = os.path.join(desktop_path, filename)

        # 跳过条件：目录、隐藏文件、快捷方式等
        skip_conditions = [
            os.path.isdir(file_path),
            filename.startswith('.'),
            os.path.islink(file_path)
        ]

        if any(skip_conditions):
            skip_reason = "目录" if os.path.isdir(file_path) else \
                "隐藏文件" if filename.startswith('.') else \
                    "快捷方式"
            logger.debug(f"跳过文件: {filename} ({skip_reason})")
            skipped_files += 1
            continue

        # 获取文件扩展名
        _, ext = os.path.splitext(filename)
        ext = ext.lower()

        # 只处理type_folders中定义的文件类型
        if ext not in target_exts:
            logger.debug(f"跳过文件: {filename} (非目标文件类型)")
            skipped_files += 1
            continue

        # 检查是否是人名文件
        if is_person_name(filename):
            person_name = os.path.splitext(filename)[0]
            folder_name = f"{person_name}"
            dest_folder = os.path.join(main_folder, folder_name)
            move_reason = f"人名分类 ({person_name})"
        else:
            # 按文件类型分类
            file_type = None
            for type_name, exts in type_folders.items():
                if ext in exts:
                    file_type = type_name
                    break

            folder_name = f"{file_type}"
            dest_folder = os.path.join(main_folder, folder_name)
            move_reason = f"文件类型分类 ({file_type})"

        # 创建目标文件夹（如果不存在）
        os.makedirs(dest_folder, exist_ok=True)

        # 移动文件
        try:
            shutil.move(file_path, os.path.join(dest_folder, filename))
            logger.info(f"移动文件: {filename} -> {time_str}/{folder_name}/ ({move_reason})")
            moved_files += 1
        except Exception as e:
            logger.error(f"移动文件失败: {filename} -> {time_str}/{folder_name}/, 错误: {str(e)}")

    # 汇总日志
    logger.info("\n===== 整理完成 =====")
    logger.info(f"已移动文件数: {moved_files}")
    logger.info(f"已跳过文件数: {skipped_files}")
    logger.info(f"创建的主文件夹: {time_str}")


if __name__ == "__main__":
    # 初始化日志记录器
    logger = setup_logger()

    try:
        classify_desktop_files(logger)
    except Exception as e:
        logger.error(f"程序运行出错: {str(e)}", exc_info=True)
